package com.songyang.mqttandothers.mqttCore;


import com.songyang.NotOnlyRedisLock.util.UniqueIdUtil;
import com.songyang.mqttandothers.common.MqttConfiguration;
import com.songyang.mqttandothers.service.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.ScheduledExecutorService;

@Slf4j
@Component
public class ClientMQTT {
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private RedisTemplate redisTemplate;
    private static ClientMQTT clientMQTT;

    @PostConstruct
    public void init() {
        clientMQTT = this;
        clientMQTT.deviceService = this.deviceService;
        clientMQTT.redisTemplate = this.redisTemplate;
//        System.out.println(deviceService == null);
    }

    public static final String HOST = MqttConfiguration.HOST;
    public static final String TOPIC1 = "yd";
    private static String clientid;
    private static MqttClient client;
    private MqttConnectOptions options;
    private String userName = "mqtt";    //非必须
    private String passWord = "mqtt";  //非必须
    private ScheduledExecutorService scheduler;

//
//    public ClientMQTT() {
//        try {
//
//        } catch (MqttException e) {
//            e.printStackTrace();
//        }
//
//    }

    public static void reconnect() {
        try {
            client.reconnect();
            log.info("客户端重新连接,连接结果：" + client.isConnected());

        } catch (MqttException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void start() {
        try {
            /**
             * 每次开启一个客户端都会重新分配一个唯一的id号码
             * 防止与之前的客户端id号码重复造成订阅不同的话题失败
             */
            clientid = UniqueIdUtil.getUniqueId(clientMQTT.redisTemplate);
            log.info("clientid:"+clientid);
            client = new MqttClient(HOST, clientid, new MemoryPersistence());
            // host为主机名，clientid即连接MQTT的客户端ID，一般以唯一标识符表示，MemoryPersistence设置clientid的保存形式，默认为以内存保存
            // MQTT的连接设置
            options = new MqttConnectOptions();
            // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录，设置为true表示每次连接到服务器都以新的身份连接
            options.setCleanSession(false);
            // 设置连接的用户名
            options.setUserName(userName);
            // 设置连接的密码
            options.setPassword(passWord.toCharArray());
            // 设置超时时间 单位为秒
            options.setConnectionTimeout(100);
            // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
            options.setKeepAliveInterval(20);
            //设置断开后重新连接
            options.setAutomaticReconnect(true);
            // 设置回调
            client.setCallback(new PushCallback());
            MqttTopic topic = client.getTopic(TOPIC1);
            //setWill方法，如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息
            //遗嘱
            options.setWill(topic, "close".getBytes(), 1, true);
//            client.connect(options);
            if (client.isConnected()) {//这里的逻辑是如果连接成功就重新连接
                client.disconnect();
            }
            client.connect(options);
            log.info("客户端成功建立连接。。。");
            String[] allTopic = clientMQTT.deviceService.getAllTopic();
            int[] Qos = new int[allTopic.length];//0：最多一次 、1：最少一次 、2：只有一次
            for (int i = 0; i < allTopic.length; i++) {
                Qos[i] = 1;
            }
            /**
             * 两个参数，第一个参数是话题的字符串你数组
             * 第二个参数是对应第一个参数的qos参数
             */
            client.subscribe(allTopic, Qos);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//
//    public static void main(String[] args) {
//        ClientMQTT client = new ClientMQTT();
//        client.start();
//    }
}
